package com.ruoyi.standingbook.toilet.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.asset.homepage.constant.StatusConstant;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.domain.vo.StatisticsToiletVo;
import com.ruoyi.common.domain.vo.ToiletErecordVo;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.standingbook.toilet.domain.Toilet;
import com.ruoyi.standingbook.toilet.domain.bo.ToiletBo;
import com.ruoyi.standingbook.toilet.domain.bo.ToiletPicBo;
import com.ruoyi.standingbook.toilet.domain.vo.ToiletImgVo;
import com.ruoyi.standingbook.toilet.domain.vo.ToiletImportDetailVo;
import com.ruoyi.standingbook.toilet.domain.vo.ToiletVo;
import com.ruoyi.standingbook.toilet.mapper.ToiletMapper;
import com.ruoyi.standingbook.toilet.service.IToiletService;
import lombok.RequiredArgsConstructor;
import org.apache.http.client.utils.DateUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 市政公厕管养Service业务层处理
 *
 * @author cc
 * @date 2023-04-30
 */
@RequiredArgsConstructor
@Service
public class ToiletServiceImpl implements IToiletService {

    private final ToiletMapper baseMapper;

    /**
     * 查询市政公厕管养
     */
    @Override
    public ToiletVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询市政公厕管养列表
     */
    @Override
    public TableDataInfo<ToiletVo> queryPageList(ToiletBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Toilet> lqw = buildQueryWrapper(bo);
        Page<ToiletVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询市政公厕管养列表
     */
    @Override
    public List<ToiletVo> queryList(ToiletBo bo) {
        LambdaQueryWrapper<Toilet> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询Excel市政公厕管养列表
     */
    @Override
    public List<ToiletVo> queryExcelList(ToiletBo bo) {
        LambdaQueryWrapper<Toilet> lqw = buildExcelQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Toilet> buildQueryWrapper(ToiletBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Toilet> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getItemName()), Toilet::getItemName, bo.getItemName());
        lqw.eq(StringUtils.isNotBlank(bo.getCommunity()), Toilet::getCommunity, bo.getCommunity());
        lqw.like(StringUtils.isNotBlank(bo.getToiletName()), Toilet::getToiletName, bo.getToiletName());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), Toilet::getAddress, bo.getAddress());
        lqw.eq(bo.getActualFrequency() != null, Toilet::getActualFrequency, bo.getActualFrequency());
        lqw.eq(bo.getThisMonthTotalFrequency() != null, Toilet::getThisMonthTotalFrequency, bo.getThisMonthTotalFrequency());
        lqw.eq(StringUtils.isNotBlank(bo.getCleaningScope()), Toilet::getCleaningScope, bo.getCleaningScope());
        lqw.eq(bo.getCount() != null, Toilet::getCount, bo.getCount());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), Toilet::getStatus, bo.getStatus());
        lqw.eq(bo.getServiceType() != null, Toilet::getServiceType, bo.getServiceType());
        lqw.eq(StringUtils.isNotBlank(bo.getToiletCategory()), Toilet::getToiletCategory, bo.getToiletCategory());
        lqw.eq(bo.getFrequency() != null, Toilet::getFrequency, bo.getFrequency());
        lqw.eq(StringUtils.isNotBlank(bo.getCleaningUser()), Toilet::getCleaningUser, bo.getCleaningUser());
        lqw.eq(StringUtils.isNotBlank(bo.getPhoneNumber()), Toilet::getPhoneNumber, bo.getPhoneNumber());
        lqw.between(params.get("beginDate") != null && params.get("endDate") != null,
            Toilet::getDate, params.get("beginDate"), params.get("endDate"));
        lqw.orderByDesc(Toilet::getCreateTime);
        lqw.orderByDesc(Toilet::getDate);
        return lqw;
    }

    private LambdaQueryWrapper<Toilet> buildExcelQueryWrapper(ToiletBo bo) {
        Map<String, Object> params = bo.getParams();
        if (params.get("endDate") == null) {
            params.put("endDate", DateUtils.formatDate(new Date(), "yyyy-MM-dd"));
        }
        LambdaQueryWrapper<Toilet> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getCommunity()), Toilet::getCommunity, bo.getCommunity());
        lqw.eq(params.get("endDate") != null, Toilet::getDate, params.get("endDate").toString().substring(0, 10));
        lqw.orderByDesc(Toilet::getCreateTime);
        lqw.orderByDesc(Toilet::getDate);
        return lqw;
    }

    /**
     * 新增市政公厕管养
     */
    @Override
    public Boolean insertByBo(ToiletBo bo) {
        Toilet add = BeanUtil.toBean(bo, Toilet.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改市政公厕管养
     */
    @Override
    public Boolean updateByBo(ToiletBo bo) {
        Toilet update = BeanUtil.toBean(bo, Toilet.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(Toilet entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除市政公厕管养
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 批量插入
     */
    @Override
    public Boolean batchInsert(List<ToiletImportDetailVo> voList) {
        if (null != voList && !voList.isEmpty()) {
            Date date = voList.get(0).getDate();
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            LambdaQueryWrapper<Toilet> lqw = Wrappers.lambdaQuery();
            lqw.eq(Toilet::getDate, date);
            this.baseMapper.delete(lqw);
        }

        List<Toilet> list = BeanCopyUtils.copyList(voList, Toilet.class);
        list.forEach(e -> {
            e.setId(null);
            e.restBase();
        });
        return this.baseMapper.insertBatch(list);
    }

    /**
     * 获取市政公厕管养电子档案信息
     *
     * @param bo
     * @return
     */
    public ToiletErecordVo getToiletErecordInfo(ToiletBo bo) {
        if (com.baomidou.mybatisplus.core.toolkit.StringUtils.isBlank(bo.getDate())) {
            throw new RuntimeException("日期不能为空");
        }
        ToiletErecordVo tev = new ToiletErecordVo();

        List<StatisticsToiletVo> communityList = baseMapper.statisticsCommunityList(); //市政公厕管养社区列表
        List<StatisticsToiletVo> toiletNumList = new ArrayList<>();

        //查询每个社区厕所数量
        for (StatisticsToiletVo stv : communityList) {
            bo.setCommunity(stv.getCommunity());
            List<StatisticsToiletVo> toiletNumCommunityList = baseMapper.statisticsToiletNumList(bo);
            StatisticsToiletVo statisticsToiletVo = new StatisticsToiletVo();
            statisticsToiletVo.setCommunity(stv.getCommunity());
            if (CollectionUtils.isNotEmpty(toiletNumCommunityList)) {
                statisticsToiletVo.setToiletNum(toiletNumCommunityList.get(0).getToiletNum());
            } else {
                statisticsToiletVo.setToiletNum(0);
            }
            toiletNumList.add(statisticsToiletVo);
        }
        tev.setToiletNumList(toiletNumList);       //市政公厕管养公厕数量列表
        List<StatisticsToiletVo> todayToiletList = baseMapper.statisticsTodayToiletList();
        tev.setToiletTodayList(todayToiletList);   //市政公厕管养今日统计列表
        List<StatisticsToiletVo> monthToiletList = baseMapper.statisticsMonthToiletList(bo);
        tev.setToiletMonthList(monthToiletList);   //市政公厕管养月统计列表
        Integer totalToiletNum = 0;    //合计公厕数量
        Integer totalTodayFrequency = 0; //合计今日清洁次数
        Integer totalThisMonthFrequency = 0;//合计本月清洁次数
        boolean communityFlag1 = false;
        boolean communityFlag2 = false;
        boolean communityFlag3 = false;
        boolean communityFlag4 = false;
        for (StatisticsToiletVo stv : toiletNumList) {
            totalToiletNum += stv.getToiletNum();
            if (stv.getCommunity().equals("田寮社区")) {
                communityFlag1 = true;
            } else if (stv.getCommunity().equals("玉律社区")) {
                communityFlag2 = true;
            } else if (stv.getCommunity().equals("长圳社区")) {
                communityFlag3 = true;
            } else if (stv.getCommunity().equals("红星社区")) {
                communityFlag4 = true;
            }
        }
        //合并月数据到今日统计列表
        for (StatisticsToiletVo stv : monthToiletList) {
            for (StatisticsToiletVo stv2 : todayToiletList) {
                if (stv.getCommunity().equals(stv2.getCommunity())) {
                    stv2.setThisMonthFrequency(stv.getFrequency());
                    break;
                }
            }
        }


        if (!communityFlag1) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("田寮社区");
            stv.setToiletNum(0);
            toiletNumList.add(stv);
        }
        if (!communityFlag2) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("玉律社区");
            stv.setToiletNum(0);
            toiletNumList.add(stv);
        }
        if (!communityFlag3) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("长圳社区");
            stv.setToiletNum(0);
            toiletNumList.add(stv);
        }
        if (!communityFlag4) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("红星社区");
            stv.setToiletNum(0);
            toiletNumList.add(stv);
        }
        communityFlag1 = false;
        communityFlag2 = false;
        communityFlag3 = false;
        communityFlag4 = false;
        for (StatisticsToiletVo stv : todayToiletList) {
            totalTodayFrequency += stv.getFrequency();
            if (stv.getCommunity().equals("田寮社区")) {
                communityFlag1 = true;
            } else if (stv.getCommunity().equals("玉律社区")) {
                communityFlag2 = true;
            } else if (stv.getCommunity().equals("长圳社区")) {
                communityFlag3 = true;
            } else if (stv.getCommunity().equals("红星社区")) {
                communityFlag4 = true;
            }
        }

        if (!communityFlag1) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("田寮社区");
            stv.setFrequency(0);
            todayToiletList.add(stv);
        }
        if (!communityFlag2) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("玉律社区");
            stv.setFrequency(0);
            todayToiletList.add(stv);
        }
        if (!communityFlag3) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("长圳社区");
            stv.setFrequency(0);
            todayToiletList.add(stv);
        }
        if (!communityFlag4) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("红星社区");
            stv.setFrequency(0);
            todayToiletList.add(stv);
        }

        communityFlag1 = false;
        communityFlag2 = false;
        communityFlag3 = false;
        communityFlag4 = false;
        for (StatisticsToiletVo stv : monthToiletList) {
            totalThisMonthFrequency += stv.getFrequency();
            if (stv.getCommunity().equals("田寮社区")) {
                communityFlag1 = true;
            } else if (stv.getCommunity().equals("玉律社区")) {
                communityFlag2 = true;
            } else if (stv.getCommunity().equals("长圳社区")) {
                communityFlag3 = true;
            } else if (stv.getCommunity().equals("红星社区")) {
                communityFlag4 = true;
            }
        }
        if (!communityFlag1) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("田寮社区");
            stv.setFrequency(0);
            monthToiletList.add(stv);
        }
        if (!communityFlag2) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("玉律社区");
            stv.setFrequency(0);
            monthToiletList.add(stv);
        }
        if (!communityFlag3) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("长圳社区");
            stv.setFrequency(0);
            monthToiletList.add(stv);
        }
        if (!communityFlag4) {
            StatisticsToiletVo stv = new StatisticsToiletVo();
            stv.setCommunity("红星社区");
            stv.setFrequency(0);
            monthToiletList.add(stv);
        }
        tev.setTotalToiletNum(totalToiletNum);    //合计公厕数量
        tev.setTotalTodayFrequency(totalTodayFrequency);    //合计今日清洁次数
        tev.setTotalThisMonthFrequency(totalThisMonthFrequency);    //合计本月清洁次数
        return tev;
    }


    @Override
    public List<ToiletImgVo> getAfterPicByDate(String date) {
        ArrayList<ToiletImgVo> list = new ArrayList<>();
        List<ToiletPicBo> toiletPicBos = baseMapper.selectPicByDate(date, StatusConstant.FINISHED);
        toiletPicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic2())) {
                ToiletImgVo toiletImgVo = new ToiletImgVo();
                toiletImgVo.setPic(" ");
                toiletImgVo.setPicUrl(e.getPic2());
                list.add(toiletImgVo);
            }
        });
        return list;
    }

    @Override
    public List<ToiletImgVo> getBeforePicByDate(String date) {
        ArrayList<ToiletImgVo> list = new ArrayList<>();
        List<ToiletPicBo> toiletPicBos = baseMapper.selectPicByDate(date, StatusConstant.FINISHED);
        toiletPicBos.forEach(e->{
            if (StringUtils.isNotBlank(e.getPic1())) {
                ToiletImgVo toiletImgVo = new ToiletImgVo();
                toiletImgVo.setPic(" ");
                toiletImgVo.setPicUrl(e.getPic1());
                list.add(toiletImgVo);
            }
        });
        return list;
    }

    @Override
    public Integer getSumByDate(String date) {
        return baseMapper.selectSumByDate(date, null, StatusConstant.FINISHED);
    }

    @Override
    public Integer getSumByDateAndCommunity(String date, String community) {
        return baseMapper.selectSumByDate(date, community, StatusConstant.FINISHED);
    }
}
